home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- *
- * Apple Developer Technical Support
- *
- * AppleEvent Coercion Handler and INIT sample
- *
- * Program: AECoercionINIT
- * File: Coercions.c - C Source
- *
- * by: C.K. Haun <TR>
- *
- * Copyright © 1991 Apple Computer, Inc.
- * All rights reserved.
- *
- *------------------------------------------------------------------------------
- * This file contains the actual coercion routines, which will be BlockMoved
- * into the System Heap and installed as System Level coercions
- * at INIT time
- *------------------------------------------------------------------------------
- */
- /* Our includes */
- #include <Types.h>
- #include <memory.h>
- #include <Errors.h>
- #include <AppleEvents.h>
-
- #define typeMyPString 'MPST'
-
- /* A structure I use in my Boolean to Char coercion */
- struct myBtoCData {
- Handle falseString;
- Handle trueString;
- };
- typedef struct myBtoCData myBtoCData, *myBtoCDataPtr, **myBtoCDataHdl;
-
- /* These first two routines coerce a PString to typeChar and back */
- /* they work on a typeMyPString, which I made up for this example */
- /* For this example, I created a typePString. A typePString would be... */
- /* descriptorType = 'MPST'
- dataHandle = (handle containing a Pascal-type string) */
- pascal OSErr CoerceCharToPString(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
- {
- #pragma unused (refCon)
- OSErr myErr = noErr;
- Str255 theString;
- Size newSize;
- /* This check isn't really necessary, since the AEM won't call you */
- /* if the data types don't match, but I wanted to used the parameters */
- /* see the Note at the end of this file for what you Can use these for */
- if ((origData == typeChar) && (toType == typeMyPString)) {
- /* first make sure the char block isn't over a PString size. If it is, I'll */
- /* truncate it to a PString and continue */
- if (theSize > 255)
- newSize = 255;
- else
- newSize = theSize;
- theString[0] = newSize;
- /* Move what we were given into my string */
- BlockMove(inPtr, (Ptr)&theString[1], newSize);
- /* Make an AppleEvent descriptor out of it */
- myErr = AECreateDesc(typeMyPString, (Ptr)&theString[0], theString[0] + 1, result);
- } else {
- myErr = errAECoercionFail;
- }
- return(myErr);
- }
-
- pascal OSErr CoercePStringToChar(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
- {
- #pragma unused (origData,toType,refCon)
- OSErr myErr = noErr;
- /* This check isn't really necessary, since the AEM won't call you */
- /* if the data types don't match, but I wanted to used the parameters */
- /* see the Note at the end of this file for what you Can use these for */
- if ((origData == typeMyPString) && (toType == typeChar)) {
- /* Don't have to worry about the size here, since a typeChar can be much larger */
- /* than a PString, just make the desriptor */
- myErr = AECreateDesc(typeChar, (Ptr)(inPtr + 1), theSize - 1, result);
- } else {
- myErr = errAECoercionFail;
- }
- return(myErr);
- }
-
- /* CoerceBooleanToChar creates a desc that says True or False. */
- /* nice for human (well, non-programmer) reading */
- /* NOTE: This coercion uses the refCon field to hold a handle */
- pascal OSErr CoerceBooleanToChar(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
- {
-
- OSErr myErr = noErr;
- /* Our string data is in our refCon, (see the Install routine) */
- /* so coerce it to something we can work with */
- myBtoCDataHdl myStrings = (myBtoCDataHdl)refCon;
- /* make sure everything is fine first */
- if (origData != typeBoolean || toType != typeChar) {
- /* something is goofy here */
- myErr = errAECoercionFail;
- } else {
- /* a boolean should be two bytes. if it isn't, I'm confused */
- if (theSize == sizeof(short)) {
- Ptr theText;
- short theBool = *((short *)inPtr);
- HLock((Handle)myStrings);
- /* I'm locking both of these even though I'll only use one */
- /* You can count cycles and see if doing two compares (before and after) */
- /* and one lock/unlock is faster, but I don't think it matters much */
- HLock((*myStrings)->falseString);
- HLock((*myStrings)->trueString);
- /* decide which string we're using */
- if (theBool)
- theText = *((*myStrings)->trueString);
- else
- theText = *((*myStrings)->falseString);
- /* And make a descriptor */
- myErr = AECreateDesc(typeChar, (theText + 1), *theText, result);
- HUnlock((*myStrings)->falseString);
- HUnlock((*myStrings)->trueString);
- HUnlock((Handle)myStrings);
- } else {
- myErr = errAECoercionFail;
- }
- }
- return(myErr);
- }
-
-
-
- /* Dummy is just a placemarker so I know where the end of is. I could */
- /* have done that a different way, but this left me some flexibility */
- void Dummy(void)
- {
- }
-
- /* ••• Note: The AEM always passes the fromType and toType to your coercion */
- /* routines. Why? You know you're not going to be called if the types aren't */
- /* correct, so why bother? */
- /* THe reason is to allow you to put all your coercions in one big function. */
- /* You can case off them, and do everything you want in one place, instead of */
- /* in scattered routines. */
- /* I am _not_ doing this in this example, because I'm grabbing memory from the */
- /* System heap to do this stuff, and the smaller I can keep the */
- /* chuncks the more likely I am to get them low in the heap, and reduce fragmentation. */
-